from PyQt4.QtCore import QObject
from PyQt4.QtCore import QSettings
from PyQt4.QtCore import SIGNAL
from datetime import datetime
from datetime import timedelta
from deploy.constants import Config


class ServiceStatus(object):

    STOPPING = 'stopping'
    STOPPED = 'stopped'
    STARTING = 'starting'
    RUNNING = 'running'
    UNKNOWN = 'unknown'

class MonitoredService(QObject):
    '''Maintains the data related to a particular monitored service.'''

    DEFAULT_CHECK_STATUS_FREQUENCY_SECONDS = 5

    def __init__(self, name, host, parent = None):
        super(MonitoredService, self).__init__(parent)

        self.name = name
        self.host = host

        self.__nextCheck = datetime.now()
        self.__lastStatus = None

    def __eq__(self, other):
        return (type(self) == type(other) and
                self.name == other.name and
                self.host == other.host)

    @property
    def status(self):
        '''Return an approximation of the status of the service.
        
        To avoid frequent expensive queries, this property caches service status,
        and limits the amount of times that the query will be performed.
        '''
        if self.__lastStatus is None or datetime.now() >= self.__nextCheck:
            currentStatus = self.checkStatus()

            if currentStatus != self.__lastStatus:
                self.__lastStatus = currentStatus
                self.emit(SIGNAL('statusChanged(PyQt_PyObject)'), self)

            settings = QSettings()
            checkFrequency, ok = settings.value(Config.SERVICE_POLLING_FREQUENCY).toInt()
            if not ok:
                checkFrequency = self.DEFAULT_CHECK_STATUS_FREQUENCY_SECONDS

            self.__nextCheck = datetime.now() + timedelta(seconds = checkFrequency)

        return self.__lastStatus

    def checkStatus(self):
        '''Get the current status of the service.
        
        This method should be overridden by child classes to provide accurate
        insight into the current status of the service.
        '''
        return ServiceStatus.UNKNOWN

    def start(self):
        '''Start the service.
        
        This method should be overriddent by child classes to properly start the service.
        '''
        pass

    def stop(self):
        '''Stop the service.
        
        This method should be overridden by child classes to properly stop the service.
        '''
        pass
